package com.littleken.code;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Random;

public class CaptcahCode {

    /**
     * 算术验证码生成方法
     * 干扰线，范围随机颜色
     * @param response
     * @return
     */
    public static String drawImageVerificate(HttpServletResponse response){
        //验证码图片大小
        int width = 100;
        int height = 30;

        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        //产生数学表达式的数字
        Random random = new Random();
        //设置背景
        g.setColor(getRandomColor(240,250));
        //设置字体
        g.setFont(new Font("微软雅黑",Font.PLAIN,22));
        //开始绘制
        g.fillRect(0,0,width,height);
        //设置干扰线
        g.setColor(getRandomColor(180,230));
        for (int i = 0; i < 100; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1= random.nextInt(60);
            int y1 = random.nextInt(60);

            g.drawLine(x,y,x1,y1);
        }

        //算术验证码表达式拼接
        int num1 = (int)(Math.random()*10 + 1);
        int num2 = (int)(Math.random()*10 + 1);

        int fuhao = random.nextInt(3);//产生符号
        String fuhaoStr = "";
        int result = 0;
        switch (fuhao){
            case 0 : fuhaoStr = "+";
                      result = num1 + num2;
                      break;
            case 1 : fuhaoStr = "-";
                      result = num1 - num2;
                      break;
            case 2: fuhaoStr = "X";
                    result = num1 * num2;
                    break;
        }
        //拼接算术表达式
        String calc = num1 + " " + fuhaoStr + " " + num2 + " = ? ";
        //设置随机颜色
        g.setColor(new Color(20 + random.nextInt(110),20 + random.nextInt(110),20 + random.nextInt(110)));
        //绘制
        g.drawString(calc,5,25);
        g.dispose();
        try{
            ImageIO.write(image,"JPEG",response.getOutputStream());
            return  String.valueOf(result);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }
    /**
     * 数字字母混合验证码生成方法
     * @param response
     * @return
     */
    public static String drawImage(HttpServletResponse response){
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            builder.append(randomChar());
        }
        String code = builder.toString();
        //验证码图片大小
        int width = 120;
        int height = 25;
        BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
        //绘制验证码
        Graphics2D g = bi.createGraphics();
        //设置文字字体,大小与颜色
        Font font = new Font("微软雅黑",Font.PLAIN,20);
        Color color = new Color(0,0,0);
        g.setFont(font);
        g.setColor(color);
        //设置背景
        g.setBackground(new Color(226,226,240));
        g.clearRect(0,0,width,height);
        //绘制矩形外边框
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(code,context);
        //计算文字的坐标和间距
        double x = (width - bounds.getWidth())/2;
        double y = (height - bounds.getHeight())/2;
        double ascent = bounds.getY();
        double baseY = y - ascent;
        g.drawString(code,(int)x,(int)baseY);
        //搞掂
        g.dispose();
        //关键一步，往浏览器输出
        try {
            ImageIO.write(bi,"jpg",response.getOutputStream());
            //刷新响应流
            response.flushBuffer();
        }catch (Exception e){
            e.printStackTrace();
        }

        return code;
    }

    /**
     * 此方法用于产生随机数
     * @return
     */
    private static char randomChar(){
        //键盘上能打出的字母与数字
        String string = "qwertyuiopasdfghjklzxcvbnm1234567890";
        Random random = new Random();
        return string.charAt(random.nextInt(string.length()));
    }

    /**
     * 产生范围随机颜色
     * @param fc
     * @param bc
     * @return
     */
    public static Color getRandomColor(int fc,int bc){
       //bc要大过 fc
        Random random = new Random();
        if(fc > 255) fc = 255;
        if(bc > 255) bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return  new Color(r,g,b);
    }
}
